package com.vcredit.creditcat.manager;

import com.alibaba.dubbo.config.annotation.Service;
import com.vcredit.creditcat.api.ICustProductManager;
import com.vcredit.creditcat.dto.creditrepository.AuthItemDto;
import com.vcredit.creditcat.dto.product.CreditCardDto;
import com.vcredit.creditcat.dto.product.MerchantProductDto;
import com.vcredit.creditcat.enumtype.MerchantProductEnum;
import com.vcredit.creditcat.model.AuthItem;
import com.vcredit.creditcat.model.AuthProccess;
import com.vcredit.creditcat.model.CardCondition;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.model.CustProductItem;
import com.vcredit.creditcat.model.CustRecommendCard;
import com.vcredit.creditcat.model.MerchantProduct;
import com.vcredit.creditcat.model.ProductCondition;
import com.vcredit.creditcat.model.ProductItem;
import com.vcredit.creditcat.model.RecommendCard;
import com.vcredit.creditcat.model.RegisterChannel;
import com.vcredit.creditcat.model.UserTempExt;
import com.vcredit.creditcat.service.AuthItemService;
import com.vcredit.creditcat.service.AuthProccessService;
import com.vcredit.creditcat.service.CardConditionService;
import com.vcredit.creditcat.service.CustProductApplyService;
import com.vcredit.creditcat.service.CustRecommendCardService;
import com.vcredit.creditcat.service.MerchantProductService;
import com.vcredit.creditcat.service.ProductConditionService;
import com.vcredit.creditcat.service.ProductItemService;
import com.vcredit.creditcat.service.RecommendCardService;
import com.vcredit.creditcat.service.UserTempService;
import com.vcredit.creditcat.service.product.CustLoanProductService;
import com.vcredit.creditcat.service.product.KKDH5UrlService;
import com.vcredit.creditcat.util.Utility;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.exception.BaseException;
import com.vcredit.framework.util.BeanUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author 李小强
 *
 */
@Service(protocol = {"protocol1"}, version = "1.0")
public class CustProductManager implements ICustProductManager {

  @Autowired
  private MerchantProductService merchantProductService;

  @Autowired
  private CustProductApplyService custProductApplyService;

  @Autowired
  private AuthProccessService authProccessService;

  @Autowired
  private ProductItemService productItemService;

  @Autowired
  private AuthItemService authItemService;

  @Autowired
  private RecommendCardService recommendCardService;

  @Autowired
  private CardConditionService cardConditionService;

  @Autowired
  private KKDH5UrlService kKDH5UrlService;

  @Autowired
  private ProductConditionService productConditionService;

  @Autowired
  private CustRecommendCardService custRecommendCardService;

  @Autowired
  private UserTempService userTempService;

  @Autowired
  private CustLoanProductService custLoanProductService;

  @Override
  public List<MerchantProductDto> queryProductDto(Long processId, Boolean technical) {
    return findMerchantProduct(merchantProductService.findByProcessId(processId), technical);
  }

  @Override
  public List<MerchantProductDto> queryProductAuth(Long processId, Boolean isAuth,
      Boolean technical) {

    return findMerchantProduct(merchantProductService.findIsAuthByProcessId(processId, isAuth),
        technical);
  }

  @Override
  public List<MerchantProductDto> queryHotProduct(Long processId, Boolean isHot,
      Boolean technical) {
    List<MerchantProductDto> sourceProducts = this.queryProductDto(processId, technical);
    List<MerchantProductDto> merchantProducts = new ArrayList<MerchantProductDto>();
    for (MerchantProductDto merchantProduct : sourceProducts) {
      if (merchantProduct.getIsHot() == isHot) {
        merchantProducts.add(merchantProduct);
      }
    }
    return merchantProducts;
  }

  private List<MerchantProductDto> findMerchantProduct(List<CustProductItem> custProducts,
      Boolean technical) {
    List<MerchantProductDto> merchantProducts = new ArrayList<MerchantProductDto>();
    for (CustProductItem product : custProducts) {
      MerchantProduct merchant = merchantProductService.findById(product.getProductId());
      // 如果产品不为null，并且已经进行技术对接
      if (merchant != null && (!technical || merchant.getIsTechnical())) {
        MerchantProductDto productDto = new MerchantProductDto();
        BeanUtil.copy(merchant, productDto);
        merchantProducts.add(productDto);
      }
    }
    return merchantProducts;
  }

  @Override
  public List<MerchantProductDto> queryApplyProduct(Long custId) {
    List<CustProductApply> custProductApplys = custProductApplyService.findByCustId(custId);
    List<MerchantProductDto> merchantProducts = new ArrayList<MerchantProductDto>();
    for (CustProductApply custProductApply : custProductApplys) {
      MerchantProductDto productDto = new MerchantProductDto();
      MerchantProduct merchant = merchantProductService.findById(custProductApply.getProductId());
      if (custProductApply != null) {
        BeanUtil.copy(custProductApply, productDto);
        BeanUtil.copy(merchant, productDto);
        merchantProducts.add(productDto);
      }
    }
    return merchantProducts;
  }

  @Override
  public MerchantProductDto queryProductById(Long productId, Long custId) {
    MerchantProduct product = merchantProductService.findById(productId);
    CustProductApply apply = custProductApplyService.findNewApplyProduct(productId, custId);
    MerchantProductDto dto = new MerchantProductDto();
    if (product != null) {
      // TODO 临时逻辑，如果是卡卡贷设置H5Url
      if (product.getProductName().equals(MerchantProductEnum.creditKak.getName())) {
        product.setH5Url(kKDH5UrlService.getH5Url(custId));
      }
      BeanUtil.copy(product, dto);

      if (apply == null) { // 未申请
        dto.setAuditResult(3);
      } else {
        BeanUtil.copy(apply, dto);
      }
    }
    return dto;
  }

  @Override
  public List<AuthItemDto> queryProductItem(Long processId, Long productId) {
    List<AuthItemDto> dto = new ArrayList<AuthItemDto>();
    AuthProccess authProccess = authProccessService.findByProcessId(processId);
    ProductItem productItem = productItemService.findByProductId(productId);
    // 产品没有认证的认证项
    List<AuthItem> authFalse = authItemService
        .getItemByCodes(
            productItem.getMinCode() - (productItem.getMinCode() & authProccess.getSuccessCode()));
    // 已经认证的产品项
    List<AuthItem> authTrue = authItemService
        .getItemByCodes(productItem.getMinCode() & authProccess.getSuccessCode());

    for (AuthItem authItem : authTrue) {
      dto.add(
          new AuthItemDto(authItem.getItemName(), authItem.getItemDesc(), authItem.getItemIcon(), 1,
              authItem.getAuthCode().toString(), authItem.getItemBasescore(),
              authItem.getItemSort()));
    }
    for (AuthItem authItem : authFalse) {
      dto.add(
          new AuthItemDto(authItem.getItemName(), authItem.getItemDesc(), authItem.getItemIcon(), 0,
              authItem.getAuthCode().toString(), authItem.getItemBasescore(),
              authItem.getItemSort()));
    }
    return dto;
  }

  @Override
  public List<AuthItemDto> queryProductItem(Long processId, Long productId, Boolean isAuth) {
    List<AuthItemDto> dto = new ArrayList<AuthItemDto>();
    AuthProccess authProccess = authProccessService.findByProcessId(processId);
    ProductItem productItem = productItemService.findByProductId(productId);
    List<AuthItem> auth = null;
    // 产品没有认证的认证项
    if (isAuth) {
      // 已经认证的产品项
      auth = authItemService
          .getItemByCodes(productItem.getMinCode() & authProccess.getSuccessCode());
      for (AuthItem authItem : auth) {
        dto.add(
            new AuthItemDto(authItem.getItemName(), authItem.getItemDesc(), authItem.getItemIcon(),
                1,
                authItem.getAuthCode().toString(), authItem.getItemBasescore(),
                authItem.getItemSort()));
      }
    } else {
      // 产品没有认证的认证项
      auth = authItemService.getItemByCodes(
          productItem.getMinCode() - (productItem.getMinCode() & authProccess.getSuccessCode()));
      for (AuthItem authItem : auth) {
        dto.add(
            new AuthItemDto(authItem.getItemName(), authItem.getItemDesc(), authItem.getItemIcon(),
                0,
                authItem.getAuthCode().toString(), authItem.getItemBasescore(),
                authItem.getItemSort()));
      }
    }
    return dto;
  }

  @Override
  public void commit(Long productId) throws BaseException, Exception {
    // ProductItem productItem =
    // productItemService.findByProductId(productId);
    // creditProductService.commit(productItem);
  }

  @Override
  public List<MerchantProductDto> queryHotProduct(Boolean isHot) {
    List<MerchantProduct> sourceProducts = merchantProductService.findHotProduct(isHot);
    if (sourceProducts != null && sourceProducts.size() > 0) {
      return BeanUtil.copy(sourceProducts, MerchantProductDto.class);
    }
    return null;
  }

  @Override
  public List<MerchantProductDto> queryTechionalProduct(Boolean isTechional) {
    List<MerchantProduct> sourceProducts = merchantProductService.findTechnialProduct(isTechional);
    if (sourceProducts != null && sourceProducts.size() > 0) {
      return BeanUtil.copy(sourceProducts, MerchantProductDto.class);
    }
    return null;
  }

  @Log
  @Override
  public List<CreditCardDto> recommendCard(Long custId, int filter, String appDesc)
      throws Exception {
    List<RecommendCard> recomendCards = null;
    List<CreditCardDto> cards = new ArrayList<CreditCardDto>();

    if (filter == 6) {// 全部
      recomendCards = recommendCardService.queryAll();
    } else {
      recomendCards = recommendCardService.findByType(filter);
    }
    this.excludeFromAppDesc(recomendCards, appDesc);

    if (null == custId || custId.toString().length() == 0) {
      for (RecommendCard card : recomendCards) {
        cards.add(new CreditCardDto(card.getCardId(), card.getCardIcon(), card.getBank(),
            card.getCardTitle(),
            card.getApplyAmount(), card.getCardContent(), ""));
      }
    } else {

      // 查询客户表相关的数据
      CustRecommendCard cRcardData = new CustRecommendCard();
      cRcardData.setCustId(custId);
      List<CustRecommendCard> list = custRecommendCardService.find(cRcardData);
      if (null == list || list.size() == 0) {
        for (RecommendCard card : recomendCards) {
          cards.add(new CreditCardDto(card.getCardId(), card.getCardIcon(), card.getBank(),
              card.getCardTitle(), card.getApplyAmount(), card.getCardContent(), ""));
        }
      } else {
        for (RecommendCard card : recomendCards) {
          boolean bs = true;

          for (int i = 0; i < list.size(); i++) {
            CustRecommendCard cRcard2 = new CustRecommendCard();
            cRcard2 = list.get(i);

            // 含有相同的ID的数据
            if (cRcard2.getCardId().equals(card.getCardId())) {
              if (cRcard2.getCardStatus() == 0) {// 判断状态
                cards.add(new CreditCardDto(card.getCardId(), card.getCardIcon(), card.getBank(),
                    card.getCardTitle(), card.getApplyAmount(), card.getCardContent(), "已申请"));
                bs = false;
                break;
              }
            }
          }

          if (bs) {
            cards.add(new CreditCardDto(card.getCardId(), card.getCardIcon(), card.getBank(),
                card.getCardTitle(), card.getApplyAmount(), card.getCardContent(), ""));

          }
        }

      }
    }

    Collections.sort(cards, new Comparator<CreditCardDto>() {
      @Override
      public int compare(CreditCardDto item1, CreditCardDto item2) {
        return item1.getApplyStatus().length() >= item2.getApplyStatus().length() ? -1 : 1;
      }
    });

    return cards;
  }


  private void excludeFromAppDesc(List<RecommendCard> recomendCards, String appDesc) {
    if (StringUtils.isEmpty(appDesc)) {
      return;
    }
    Iterator<RecommendCard> iterator = recomendCards.iterator();
    while (iterator.hasNext()) {
      boolean unfit = false;
      RecommendCard card = iterator.next();
      List<CardCondition> cardConditions = cardConditionService
          .findByIdAndType(card.getCardId(), 0);
      if (Utility.isNullOrEmpty(cardConditions)) {
        unfit = true;
      } else {
        for (CardCondition condition : cardConditions) {
          String conditionValue = condition.getConditionValue();
          if ((!StringUtils.isEmpty(conditionValue)) &&
              appDesc.trim().toLowerCase().equals(conditionValue.toLowerCase().trim())) {
            unfit = false;
            break;
          } else {
            unfit = true;
          }
        }
      }

      if (unfit) {
        iterator.remove();
      }
    }

  }

  /**
   * 查询所有产品
   */
  @Override
  public List<MerchantProductDto> queryAllProductDto() {
    List<MerchantProduct> list = merchantProductService.findAllList();
    return BeanUtil.copy(list, MerchantProductDto.class);
  }

  @Log
  @Override
  public List<MerchantProductDto> queryFitProduct(Long custId, String answers, String appDesc) {
    List<MerchantProduct> list = merchantProductService.findAllMerchantProduct();

    //this.excludeFromPlantform(list, appDesc);
    this.excludeFromChannel(list, custId);
    this.excludeFromSelect(list, answers);
    this.excludeFromTechical(list);

    return this.convertMerchantProductDto(custId, list);
  }

  //不显示技术对接的产品
  private void excludeFromTechical(List<MerchantProduct> list) {
    Iterator<MerchantProduct> iterator = list.iterator();
    while (iterator.hasNext()) {
      MerchantProduct next = iterator.next();
      if (next.getIsTechnical()) {
        iterator.remove();
      }
    }
  }

  //转Dto
  private List<MerchantProductDto> convertMerchantProductDto(Long custId,
      List<MerchantProduct> list) {
    if (null == custId) {
      return BeanUtil.copy(list, MerchantProductDto.class);
    }
    List<CustProductApply> custProductApplys = custProductApplyService.findByCustId(custId);
    if (Utility.isNullOrEmpty(custProductApplys)) {
      return BeanUtil.copy(list, MerchantProductDto.class);
    }

    List<MerchantProductDto> merchantProductDtos = new ArrayList<>(list.size());
    for (MerchantProduct product : list) {
      MerchantProductDto productDto = new MerchantProductDto();
      BeanUtil.copy(product, productDto);
      for (CustProductApply custProductApply : custProductApplys) {
        if (product.getProductId() == custProductApply.getProductId().longValue()) {
          BeanUtil.copy(custProductApply, productDto);
          break;
        }
      }

      merchantProductDtos.add(productDto);
    }
    return merchantProductDtos;
  }

  private void excludeFromPlantform(List<MerchantProduct> merchantProducts, String appDesc) {
    if (StringUtils.isEmpty(appDesc)) {
      appDesc = "creditcat;1.3.1;ios";
    }
    Iterator<MerchantProduct> iterator = merchantProducts.iterator();
    while (iterator.hasNext()) {
      boolean unfit = false;
      MerchantProduct merchantProduct = iterator.next();
      List<ProductCondition> conditions = productConditionService
          .findByProductIdAndType(merchantProduct.getProductId(), "3");
      if (Utility.isNullOrEmpty(conditions)) {
        unfit = true;
      } else {
        for (ProductCondition condition : conditions) {
          String conditionValue = condition.getConditionValue();
          if ((!StringUtils.isEmpty(conditionValue)) &&
              appDesc.trim().toLowerCase().equals(conditionValue.toLowerCase().trim())) {
            unfit = false;
            break;
          } else {
            unfit = true;
          }
        }
      }

      if (unfit) {
        iterator.remove();
      }
    }
  }

  /**
   * 渠道中过滤
   *
   * @param merchantProducts
   * @param custId
   * @return
   */
  private void excludeFromChannel(List<MerchantProduct> merchantProducts, Long custId) {

    if (ObjectUtils.equals(null, custId)) {
      return;
    }

    List<UserTempExt> myApllyedChannel = userTempService.findMyApllyedChannel(custId);
    if (Utility.isNullOrEmpty(myApllyedChannel)) {
      return;
    }

    Iterator<MerchantProduct> iterator = merchantProducts.iterator();
    while (iterator.hasNext()) {
      MerchantProduct merchantProduct = iterator.next();
      for (UserTempExt ext : myApllyedChannel) {
        RegisterChannel registerChannel = ext.getRegisterChannel();
        if (StringUtils
            .equals(registerChannel.getChannelDesc(), merchantProduct.getProductName())) {
          iterator.remove();
        }
      }
    }
  }

  private void excludeFromSelect(List<MerchantProduct> merchantProducts, String answers) {
    if (answers.contains("金额不限") && answers.contains("期限不限") && answers.contains("类型不限")) {
      return;
    }
    String[] answerList = answers.split(";");

    Iterator<MerchantProduct> iterator = merchantProducts.iterator();
    while (iterator.hasNext()) {
      MerchantProduct merchantProduct = iterator.next();

      boolean unfit = false;
      List<ProductCondition> productConditions = productConditionService
          .findByProductIdAndSelected(merchantProduct.getProductId());
      if (productConditions.size() > 0) {
        for (ProductCondition productCondition : productConditions) {
          int conditionType = Integer.parseInt(productCondition.getConditionType());
          switch (conditionType) {
            case 0:
              if (answerList[0].equals("金额不限")) {
                continue;
              }
              break;
            case 1:
              if (answerList[1].equals("期限不限")) {
                continue;
              }
              break;
            case 2:
              if (answerList[2].equals("类型不限")) {
                continue;
              }
              break;
            default:
              break;
          }

          unfit = unfit || this.unfit(answerList[conditionType], productCondition.getConditionValue());
        }
      } else {
        unfit = true;
      }

      if (unfit) {
        iterator.remove();
      }
    }
  }

  @Override
  public int getSuccessLoanApplyCount(Long custId) {
    int count = custLoanProductService.getSuccessLoanCount(custId);
    return count;
  }

  private Boolean unfit(String answers, String conditionValue) {
    boolean fit = false;
    if (StringUtils.isEmpty(conditionValue)) {
      return false;
    }
    if (conditionValue.contains(";")) {
      String[] conditions = conditionValue.split(";");
      if (conditions.length > 1) {
        for (String condition : conditions) {
          if (StringUtils.isEmpty(condition)) {
            continue;
          }
          if (answers.equals(condition)) {
            fit = true;
            break;
          }
        }
      } else {
        if (answers.equals(conditions[0])) {
          fit = true;
        }
      }
    } else {
      if (answers.equals(conditionValue)) {
        fit = true;
      }
    }
    return !fit;
  }
}
